#include "httphelper.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <mutex>
#include <QJsonDocument>

std::unique_ptr<HttpHelper> HttpHelper::instance_ = nullptr;
#define SERVER_URL "http://10.200.14.253:8083/"


HttpHelper *HttpHelper::instance()
{
    static std::once_flag flag;
    std::call_once(flag,[&](){
        instance_.reset(new HttpHelper());
    });
}

HttpHelper::~HttpHelper()
{
    if(networkManager)
    {
        delete networkManager;
        networkManager = nullptr;
    }
}

void HttpHelper::slot_GetmediaInfo()
{
    sendRequest(MEDIALIST,false);
}

void HttpHelper::slot_Register(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updeteTime"] = "";
    rootObj["params"] = paramsObj;
    rootObj["userId"] = 0;
    rootObj["userName"] = infomap["userName"].toString();
    rootObj["nickName"] = infomap["nickName"].toString();
    rootObj["passwd"] = infomap["passwd"].toString();

    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(REGISTER,true,jsondata);
}

void HttpHelper::slot_Login(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updeteTime"] = "";
    rootObj["params"] = paramsObj;
    rootObj["userId"] = 0;
    rootObj["userName"] = infomap["userName"].toString();
    rootObj["nickName"] = infomap["nickName"].toString();
    rootObj["passwd"] = infomap["passwd"].toString();

    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(LOGIN,true,jsondata);
}

void HttpHelper::slot_LoginOut(const QVariantMap &infomap)
{
    QJsonObject rootObj;
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(LOGINOUT,true,jsondata);
}

void HttpHelper::slot_AddmediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updeteTime"] = "";
    rootObj["params"] = paramsObj;
    rootObj["mediaId"] = 0;
    rootObj["userId"] = 0;
    rootObj["mediaUrl"] = infomap["mediaUrl"].toString();
    rootObj["mediaTitle"] = infomap["mediaTitle"].toString();
    rootObj["prderNum"] = 0;

    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(ADDMEDIA,true,jsondata);
}

void HttpHelper::slot_EditmediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updeteTime"] = "";
    rootObj["params"] = paramsObj;
    rootObj["mediaId"] = 0;
    rootObj["userId"] = 0;
    rootObj["mediaUrl"] = infomap["mediaUrl"].toString();
    rootObj["mediaTitle"] = infomap["mediaTitle"].toString();
    rootObj["orderNum"] = 0;
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(EDITMEDIA,true,jsondata);
}

void HttpHelper::slot_RemovemediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updeteTime"] = "";
    rootObj["params"] = paramsObj;
    rootObj["mediaId"] = 0;
    rootObj["userId"] = 0;
    rootObj["mediaUrl"] = infomap["mediaUrl"].toString();
    rootObj["mediaTitle"] = infomap["mediaTitle"].toString();
    rootObj["orderNum"] = 0;

    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(REMOVEMEDIA,true,jsondata);
}

void HttpHelper::HandleReply(const QByteArray &data)
{
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data,&parseError);
    QByteArray jsonstring = jsonDoc.toJson(QJsonDocument::Indented);
    qDebug() <<"json data: " << jsonstring.constData();
    //检查是否出错
    if(parseError.error != QJsonParseError::NoError)
    {
        qDebug() <<"JSON解析出错: " << parseError.errorString() <<"位置: " << parseError.offset;
        return;
    }
    //
    if(jsonDoc.isObject())
    {
        QJsonObject jsonObj = jsonDoc.object();
        bool operationSuccess = (jsonObj["code"].toInt() == 200);
        int reponseTyoe = jsonObj["responseType"].toInt();
        if(reponseTyoe != MEDIALIST)
        {
            if(reponseTyoe == LOGIN && operationSuccess)
            {
                token = jsonObj["msg"].toString();
            }
            emit sig_Operator(static_cast<REQUESTTYPE>(reponseTyoe),operationSuccess);
        }
        else if(reponseTyoe == MEDIALIST && operationSuccess)
        {
            QJsonValue dataValue = jsonObj["data"];
            //检查是否为数组
            QVector<QVariantMap> mediaList;
            if(dataValue.isArray())
            {
                QJsonArray dataArray = dataValue.toArray();
                //遍历数组提取里面的视频url和title
                for(const QJsonValue &itemValue : dataArray)
                {
                    if(itemValue.isObject())
                    {
                        QJsonObject itemObj = itemValue.toObject();
                        QVariantMap mediaItem;
                        if(itemObj.contains("mediaTitle") && itemObj["mediaTitle"].isString())
                        {
                            mediaItem["mediaTitle"] = itemObj["mediaTitle"].isString();
                        }
                        if(itemObj.contains("mediaUrl") && itemObj["mediaUrl"].isString())
                        {
                            mediaItem["mediaUrl"] = itemObj["mediaUrl"].isString();
                        }
                        mediaList.append(mediaItem);
                    }
                }
            }
            emit sig_MediaInfo(mediaList);
        }
        if(!operationSuccess)
        {
            qDebug()<<"操作失败：" << jsonObj["msg"].toString();
        }
    }
}

void HttpHelper::onReplyFinished(QNetworkReply *reply)
{
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    QNetworkReply::NetworkError errorType = reply->error();
    QString errorMsg = reply->errorString();
    qDebug() <<"request URL: "<< reply->url().toString();
    qDebug() <<"HTTP status code: " <<statusCode.toInt();
    qDebug() <<"Error Type: " <<errorType;
    qDebug() <<"Error Message: " << errorMsg;

    QByteArray response = reply->readAll();
    qDebug() << "response data: " <<QString::fromUtf8(response);

    if(errorType == QNetworkReply::NoError)
    {
        HandleReply(response);
    }
    else
    {
       switch (errorType) {
       case QNetworkReply::ConnectionRefusedError:
           qDebug()<<"连接拒绝，未开放";
           break;
       case QNetworkReply::HostNotFoundError:
           qDebug()<<"连接拒绝，未开放";
           break;
       case QNetworkReply::TimeoutError:
           qDebug()<<"请求超时";
           break;
       case QNetworkReply::ContentNotFoundError:
           qDebug()<<"连接没找到";
           break;
       default:
           qDebug()<<"其他错误"<< errorMsg;
       }
    }
    reply->deleteLater();
}

void HttpHelper::sendGetRequest(const QNetworkRequest &request)
{
    networkManager->get(request);
}

void HttpHelper::sendPostRequest(QNetworkRequest &request, const QByteArray &data)
{
    networkManager->post(request,data);
}
#include<QUrl>

void HttpHelper::sendRequest(const REQUESTTYPE type, bool isPost, const QByteArray data)
{
    QUrl url = QUrl::fromUserInput(requestAddrs[type]);
    if(!url.isValid())
    {
        qDebug() <<"url无效";
        return;
    }
    QNetworkRequest request(url);
    //指定数据为json
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
    //设置token
    QByteArray authHeader = token.toUtf8();
    request.setRawHeader("Authorization",authHeader);
    isPost ? sendPostRequest(request,data) : sendGetRequest(request);
}

HttpHelper::HttpHelper(QObject *parent)
    : QObject(parent)
    ,networkManager(new QNetworkAccessManager(this))//初始列表

{
    requestAddrs[REGISTER] = QString(SERVER_URL) + "user/register";
    requestAddrs[LOGIN] = QString(SERVER_URL) + "user/login";
    requestAddrs[LOGINOUT] = QString(SERVER_URL) + "user/loginput";
    requestAddrs[MEDIALIST] = QString(SERVER_URL) + "user/list";
    requestAddrs[ADDMEDIA] = QString(SERVER_URL) + "user/add";
    requestAddrs[EDITMEDIA] = QString(SERVER_URL) + "user/edit";
    requestAddrs[REMOVEMEDIA] = QString(SERVER_URL) + "user/remove";

    connect(networkManager,&QNetworkAccessManager::finished,this,&HttpHelper::onReplyFinished);
}
